#if !defined(__SOUS_SYSTEME_H)
#define __SOUS_SYSTEME_H

#include "Incopiable.h"
#include "erreur.h"

extern const char sous_systeme_deja_initialise[];
extern const char sous_systeme_pas_encore_initialise[];

/**
 * Représente un "sous-système" : quelqu'un prend la responsabilité de l'instancier (il est RAII)
 * et dans les limites où il est instancié tout le monde peut y faire référence.
 */
template <class T>
struct sous_systeme : Incopiable {
	static sous_systeme<T> &instance() {
		if(!instance_)
			throw une_erreur<sous_systeme_pas_encore_initialise>();
		return *instance_;
	}
	
	sous_systeme() throw(erreur) {
		if(instance_)
			throw une_erreur<sous_systeme_deja_initialise>();
		T::initialiser();
		instance_ = this;
	}
	
	virtual ~sous_systeme() {
		T::fermer();
		instance_ = 0;
	}
private:
	static sous_systeme<T> *instance_;
};

/**
 * Classe dependant_de : représente tout objet dépendant du sous système
 * de manière à ce que la création d'un de ces objets soit impossible
 * tant que le sous système n'est pas "allumé".
 */
template <class T>
class dependant_de {
    sous_systeme<T> &g_;
public:
    dependant_de() throw(erreur) : g_(sous_systeme<T>::instance()) {}
	virtual ~dependant_de() throw() {}
};
//////

// Une autre syntaxe est prohibée par VC++6
template <class T>
sous_systeme<T> *sous_systeme<T>::instance_ = 0;

#endif
